#ifndef ENGINE_H_
#define ENGINE_H_

#include "Enums.h"
#include "Move.h"
#include "MoveTracker.h"
#include "Player.h"
#include "../Board/Chessboard.h"
#include "../Board/Square.h"
#include "../Pieces/Piece.h"


#include <vector>
#include <string>
using namespace std;

namespace Core
{
	class Engine
	{
	public:
		static const int PLR_PIECES = 16;

		static Engine * instance();
		static int humans() { return _humans; }
		static void humans(int val) { _humans = val; }
		static void reset();
		~Engine(void);

		Player * whitePlr() const { return _wPlr; }
		Player * blackPlr() const { return _bPlr; }
		ChColor whosPlaying() const;
		ChStatus status() const;
		ChStatus analyzeMove(const Move * move);
		ChStatus analyzeOverallStatus(const Move * last);
		bool isDrawn(const Move * last);
		bool hasCheckCondition() const;
		int moveNumber() const;
		void move(int r0, int c0, int r1, int c1, bool analyze = false);
		const Move * undoMove();
		const Move * redo();
		const Move * lastMove() const;

		const Chessboard * chessboard() const { return _board; }
		string saveToString() const;
		static void loadFromString(const string &s);

	private:
		Engine();
		static Engine * _instance;
		static int _humans;
		Chessboard * _board;
		Player * _wPlr;
		Player * _bPlr;
		Piece * _wKing;
		Piece * _bKing;
		ChColor _whosPlaying;
		int _trivialMovesNum;
		MoveTracker * _tracker;
	
		void dispose();
		void init();
		void doMove(const Move * move);
		void undoMove(const Move * move);
		void switchTurn();

		ChColor whoIsChecked () const;
	};
}

#endif
